<HTML>
<HEAD>
<TITLE>Decision Helper</TITLE>
<META http-equiv=Content-Type content="text/html; charset=utf-8">

<SCRIPT LANGUAGE="JavaScript">
<!--
function Compress(strNormalString)
{
  alert("压缩前长度：" + strNormalString.length);
  var strCompressedString = "";

  var ht = new HashTable;
  for(i = 0; i < 128; i++) {
    var e = new HashTableElement;
    e.key = i;
    e.code = i;
    ht.Insert(e);
  }

  var used = 128;
  var intLeftOver = 0;
  var intOutputCode = 0;
  var pcode = 0;
  var ccode = 0;
  var k = 0;

  for(var i=0; i<strNormalString.length; i++) {
    ccode = strNormalString.charCodeAt(i);
    k = (pcode << 8) | ccode;
    if((intSearch = ht.Search(k)) != null) {
      pcode = intSearch;
    } else {
      intLeftOver += 12;
      intOutputCode <<= 12;
      intOutputCode |= pcode;
      pcode = ccode;
      if(intLeftOver >= 16) {
        strCompressedString += String.fromCharCode( intOutputCode >> ( intLeftOver - 16 ) );
        intOutputCode &= (Math.pow(2,(intLeftOver - 16)) - 1);
        intLeftOver -= 16;
      }
      if(used < 4096) {
        used ++;
        var e = new HashTableElement;
        e.key = k;
        e.code = used - 1;
        ht.Insert(e);
      }
    }
  }

  if(pcode != 0) {
    intLeftOver += 12;
    intOutputCode <<= 12;
    intOutputCode |= pcode;
  }

  if(intLeftOver >= 16) {
    strCompressedString += String.fromCharCode( intOutputCode >> ( intLeftOver - 16 ) );
    intOutputCode &= (Math.pow(2,(intLeftOver - 16)) - 1);
    intLeftOver -= 16;
  }

  if( intLeftOver > 0) {
    intOutputCode <<= (16 - intLeftOver);
    strCompressedString += String.fromCharCode( intOutputCode );
  }

  alert("压缩后长度：" + strCompressedString.length);
  return strCompressedString;
}

function Decompress(strCompressedString)
{
  var strNormalString = "";
  var ht = new Array;
  
  for(i = 0; i < 128; i++)
  {
    ht[i] = String.fromCharCode(i);
  }

  var used = 128;
  var intLeftOver = 0;
  var intOutputCode = 0;
  var ccode = 0;
  var pcode = 0;
  var key = 0;

  for(var i=0; i<strCompressedString.length; i++) {
    intLeftOver += 16;
    intOutputCode <<= 16;
    intOutputCode |= strCompressedString.charCodeAt(i);
    
    while(1) {
      if(intLeftOver >= 12) {
        ccode = intOutputCode >> (intLeftOver - 12);
        if( typeof( key = ht[ccode] ) != "undefined" ) {
         strNormalString += key;
          if(used > 128) {
            ht[ht.length] = ht[pcode] + key.substr(0, 1);
          }
         pcode = ccode;
        } else {
          key = ht[pcode] + ht[pcode].substr(0, 1);
          strNormalString += key;
          ht[ht.length] = ht[pcode] + key.substr(0, 1);
          pcode = ht.length - 1;
        }

        used ++;
        intLeftOver -= 12;
        intOutputCode &= (Math.pow(2,intLeftOver) - 1);
      } else {
        break;
      }
    }
  }
  return strNormalString;
}

function HashTableElement()
{
  this.key = null;
  this.code = null;
}

function HashTable()
{
  this.ht = new Array(4099);

  this.Search = function(keyword) {
    var arr = this.ht[keyword%4099];
    if(typeof(arr) != "undefined") {
      for(i = 0; i < arr.length; i ++) {
        if(arr[i].key == keyword) return arr[i].code;
      }
    }
     return null;
  }

  this.Insert = function(e) {
    var arr = this.ht[e.key%4099];
    if(typeof(arr) == "undefined") {
      arr = new Array();
      arr[0] = e;
      this.ht[e.key%4099] = arr;
    } else {
      arr[arr.length] = e;
    }
  }
}
//-->
</SCRIPT>
</HEAD>  
<body>
压缩前：<br>
<input name=inputSrc><br>
压缩后：<br>
<input name=inputDest><br>
<br>
<input type=button value=压缩 onclick="inputDest.value=Compress(inputSrc.value);">
&nbsp;&nbsp;&nbsp;&nbsp;
<input type=button value=解压 onclick="alert(Decompress(inputDest.value));">
</body>
<html>